package org.example.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.example.entity.Permission;
import org.example.entity.Role;
import org.example.mapper.PermissionMapper;
import org.example.mapper.RoleMapper;
import org.example.mapper.RolePermissionMapper;
import org.example.mapper.UserRoleCompanyRelationMapper;

import org.example.common.result.PageResult;
import org.example.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.ArrayList;
import java.util.Map;

/**
 * 角色服务实现类
 */
@Slf4j
@Service
public class RoleServiceImpl implements RoleService {
    
    @Autowired
    private RoleMapper roleMapper;
    
    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    
    @Autowired
    private PermissionMapper permissionMapper;
    
    @Autowired
    private UserRoleCompanyRelationMapper userRoleCompanyRelationMapper;
    

    
    // ========== 平台端角色管理方法实现 ==========
    
    @Override
    public PageResult<Role> getPlatformRoleList(Integer page, Integer size, String roleName) {
        // 构建查询条件
        com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role> queryWrapper = 
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role>()
                .eq("scope", "platform")
                .eq("app", "platform")
                .eq("is_active", 1);
        
        // 添加搜索条件
        if (roleName != null && !roleName.trim().isEmpty()) {
            queryWrapper.like("role_name", roleName);
        }
        
        // 分页查询
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<Role> pageParam = 
            new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page, size);
        
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<Role> result = 
            roleMapper.selectPage(pageParam, queryWrapper);
        
        // 修复类型转换问题：将Integer转换为Long
        return new PageResult<>(
            Long.valueOf(page), 
            Long.valueOf(size), 
            result.getTotal(), 
            result.getRecords()
        );
    }
    
    @Override
    public Role getPlatformRoleById(Long roleId) {
        // 放宽校验：直接按ID返回，避免因scope/app中英文不一致导致空
        return roleMapper.selectById(roleId);
    }
    
    @Override
    @Transactional
    public Role createPlatformRole(Role role) {
        // 设置平台端角色属性
        role.setScope("platform");
        role.setApp("platform");
        role.setCompanyId(null); // 平台端不关联公司，避免外键约束失败
        role.setIsActive(1);
        
        // 平台端名称全局唯一：在代码层先校验
        com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role> dupCheck =
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role>()
                .eq("app", "platform")
                .eq("scope", "platform")
                .eq("role_name", role.getRoleName());
        Long exists = roleMapper.selectCount(dupCheck);
        if (exists != null && exists > 0) {
            throw new IllegalArgumentException("平台端角色名称已存在: " + role.getRoleName());
        }

        // 插入角色
        roleMapper.insert(role);
        return role;
    }
    
    @Override
    @Transactional
    public Role updatePlatformRole(Role role) {
        // 确保是平台端角色
        Role existingRole = getPlatformRoleById(role.getId());
        if (existingRole == null) {
            throw new RuntimeException("角色不存在或不是平台端角色");
        }
        // 名称排重（排除自己）
        if (role.getRoleName() != null && !role.getRoleName().trim().isEmpty()) {
            com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role> dupCheck =
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role>()
                    .eq("app", "platform")
                    .eq("scope", "platform")
                    .eq("role_name", role.getRoleName().trim())
                    .ne("id", role.getId());
            Long exists = roleMapper.selectCount(dupCheck);
            if (exists != null && exists > 0) {
                throw new IllegalArgumentException("平台端角色名称已存在: " + role.getRoleName());
            }
        }
        
        // 更新角色信息
        roleMapper.updateById(role);
        return getPlatformRoleById(role.getId());
    }
    
    @Override
    @Transactional
    public void deletePlatformRole(Long roleId) {
        Role role = getPlatformRoleById(roleId);
        if (role == null) {
            throw new RuntimeException("角色不存在或不是平台端角色");
        }
        
        // 1. 查找默认角色（角色名为"默认角色"）
        Role defaultRole = roleMapper.selectOne(
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role>()
                .eq("role_name", "默认角色")
                .eq("scope", "platform")
                .eq("app", "platform")
                .eq("is_active", 1)
        );
        
        if (defaultRole == null) {
            throw new RuntimeException("默认角色不存在，无法删除当前角色");
        }
        
        // 2. 将该角色下的用户转移到默认角色（更新users.primary_role_id）
        roleMapper.transferUsersToDefaultRole(roleId, defaultRole.getId());
        
        // 3. 删除角色权限关联关系
        rolePermissionMapper.deleteByRoleId(roleId);
        
        // 4. 删除角色
        roleMapper.deleteById(roleId);
    }
    
    @Override
    @Transactional
    public void assignPlatformRolePermissions(Long roleId, List<Long> permissionIds) {
        Role role = getPlatformRoleById(roleId);
        if (role == null) {
            throw new RuntimeException("角色不存在或不是平台端角色");
        }
        
        // 1. 删除该角色现有的权限关联
        rolePermissionMapper.deleteByRoleId(roleId);
        
        // 2. 如果有新的权限，则插入新的权限关联
        if (permissionIds != null && !permissionIds.isEmpty()) {
            rolePermissionMapper.batchInsert(roleId, permissionIds);
        }
        
        // 3. 更新roles表的permissions JSON字段（可选，用于快速查询）
        String permissionsJson = permissionIds != null && !permissionIds.isEmpty() 
            ? "[" + String.join(",", permissionIds.stream().map(String::valueOf).toList()) + "]"
            : "[]";
        
        Role updateRole = new Role();
        updateRole.setId(roleId);
        updateRole.setPermissions(permissionsJson);
        roleMapper.updateById(updateRole);
    }
    
    @Override
    @Transactional
    public void updatePlatformRoleStatus(Long roleId, Integer isActive) {
        Role role = getPlatformRoleById(roleId);
        if (role == null) {
            throw new RuntimeException("角色不存在或不是平台端角色");
        }
        
        // 更新角色状态
        Role updateRole = new Role();
        updateRole.setId(roleId);
        updateRole.setIsActive(isActive);
        roleMapper.updateById(updateRole);
    }
    
    @Override
    public List<Permission> getPlatformPermissions() {
        return permissionMapper.getAllActivePermissions();
    }
    
    @Override
    public List<Permission> getPermissionsByRoleId(Long roleId) {
        // 1. 根据roleId查询role_permission关联表，获取permissionIds
        List<Long> permissionIds = rolePermissionMapper.getPermissionIdsByRoleId(roleId);
        if (permissionIds.isEmpty()) {
            return new ArrayList<>();
        }
        // 2. 根据permissionIds查询permission表，获取权限详情
        return permissionMapper.selectBatchIds(permissionIds);
    }
    
    @Override
    public List<Map<String, Object>> countUsersByRoleId() {
        // 平台端统计切换为从 user_role_platform_relations 统计
        return roleMapper.countPlatformUsersByRoleId();
    }
    
    // ========== 企业端角色管理方法实现 ==========
    
    @Override
    public List<Role> getEnterpriseRoleList(Long companyId) {
        // 返回该企业下的所有企业端角色（不再依赖用户关系表）
        com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role> queryWrapper =
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role>()
                .eq("company_id", companyId)
                .eq("app", "enterprise")
                .eq("scope", "tenant")
                .eq("is_active", 1)
                .orderByDesc("created_at");

        return roleMapper.selectList(queryWrapper);
    }
    
    @Override
    @Transactional
    public Role save(Role role) {
        // 企业端：同一公司内角色名唯一（代码层校验）
        if ("enterprise".equals(role.getApp()) && role.getCompanyId() != null) {
            com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role> dupCheck =
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role>()
                    .eq("app", "enterprise")
                    .eq("scope", "tenant")
                    .eq("company_id", role.getCompanyId())
                    .eq("role_name", role.getRoleName());
            Long exists = roleMapper.selectCount(dupCheck);
            if (exists != null && exists > 0) {
                throw new IllegalArgumentException("该企业下角色名称已存在: " + role.getRoleName());
            }
        }

        roleMapper.insert(role);
        return role;
    }
    
    @Override
    public Role getById(Long roleId) {
        return roleMapper.selectById(roleId);
    }
    
    @Override
    @Transactional
    public Role updateById(Role role) {
        // 企业端：名称排重（同公司内，排除自己）
        if (role.getRoleName() != null && !role.getRoleName().trim().isEmpty()) {
            // 需要先查出该角色的公司ID（如果未传 companyId）
            Long companyId = role.getCompanyId();
            if (companyId == null) {
                Role db = roleMapper.selectById(role.getId());
                if (db != null) {
                    companyId = db.getCompanyId();
                }
            }
            if (companyId != null) {
                com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role> dupCheck =
                    new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role>()
                        .eq("app", "enterprise")
                        .eq("scope", "tenant")
                        .eq("company_id", companyId)
                        .eq("role_name", role.getRoleName().trim())
                        .ne("id", role.getId());
                Long exists = roleMapper.selectCount(dupCheck);
                if (exists != null && exists > 0) {
                    throw new IllegalArgumentException("该企业下角色名称已存在: " + role.getRoleName());
                }
            }
        }

        roleMapper.updateById(role);
        return getById(role.getId());
    }
    
    @Override
    @Transactional
    public boolean removeById(Long roleId) {
        try {
            // 1. 检查角色是否被使用
            int userCount = userRoleCompanyRelationMapper.countUsersByRoleId(roleId);
            if (userCount > 0) {
                log.warn("角色 {} 下还有 {} 个用户，执行软删除", roleId, userCount);
            }
            
            // 2. 禁用该角色下的所有用户关联（软删除）
            int disabledCount = userRoleCompanyRelationMapper.disableByRoleId(roleId);
            log.info("已禁用角色 {} 下的 {} 个用户关联", roleId, disabledCount);
            
            // 3. 删除角色权限关联关系
            rolePermissionMapper.deleteByRoleId(roleId);
            
            // 4. 软删除角色（设置is_active=0）
            Role role = new Role();
            role.setId(roleId);
            role.setIsActive(0);
            // 注意：这里需要添加updatedAt字段，如果没有这个字段，可以注释掉
            // role.setUpdatedAt(LocalDateTime.now());
            
            int result = roleMapper.updateById(role);
            if (result > 0) {
                log.info("角色 {} 软删除成功", roleId);
            }
            
            return result > 0;
        } catch (Exception e) {
            log.error("软删除角色失败: roleId={}", roleId, e);
            throw new RuntimeException("软删除角色失败: " + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public boolean softRemoveById(Long roleId) {
        // 这个方法与removeById功能相同，为了接口兼容性保留
        return removeById(roleId);
    }
    
    @Override
    @Transactional
    public boolean restoreRole(Long roleId) {
        try {
            // 恢复角色（设置is_active=1）
            Role role = new Role();
            role.setId(roleId);
            role.setIsActive(1);
            // 注意：这里需要添加updatedAt字段，如果没有这个字段，可以注释掉
            // role.setUpdatedAt(LocalDateTime.now());
            
            int result = roleMapper.updateById(role);
            if (result > 0) {
                log.info("角色 {} 恢复成功", roleId);
            }
            
            return result > 0;
        } catch (Exception e) {
            log.error("恢复角色失败: roleId={}", roleId, e);
            throw new RuntimeException("恢复角色失败: " + e.getMessage());
        }
    }
    
    @Override
    public List<Role> getDeletedRoles() {
        // 查询所有已删除的角色（is_active=0）
        com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role> queryWrapper = 
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role>()
                .eq("is_active", 0)
                .orderByDesc("id");
        
        return roleMapper.selectList(queryWrapper);
    }
    
    @Override
    @Transactional
    public void removeRolePermissions(Long roleId) {
        // 删除角色的所有权限关联
        rolePermissionMapper.deleteByRoleId(roleId);
    }
    
    @Override
    @Transactional
    public void assignRolePermissions(Long roleId, List<Long> permissionIds) {
        // 1. 删除该角色现有的权限关联
        rolePermissionMapper.deleteByRoleId(roleId);
        
        // 2. 如果有新的权限，则插入新的权限关联
        if (permissionIds != null && !permissionIds.isEmpty()) {
            rolePermissionMapper.batchInsert(roleId, permissionIds);
        }
        
        // 3. 更新roles表的permissions JSON字段（可选，用于快速查询）
        String permissionsJson = permissionIds != null && !permissionIds.isEmpty() 
            ? "[" + String.join(",", permissionIds.stream().map(String::valueOf).toList()) + "]"
            : "[]";
        
        Role updateRole = new Role();
        updateRole.setId(roleId);
        updateRole.setPermissions(permissionsJson);
        roleMapper.updateById(updateRole);
    }
    
    @Override
    public List<Permission> getEnterprisePermissions() {
        // 查询企业端权限列表
        com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Permission> queryWrapper = 
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Permission>()
                .eq("app", "enterprise")
                .eq("is_active", 1)
                .orderByAsc("permission_code");
        
        return permissionMapper.selectList(queryWrapper);
    }
    
    @Override
    public Role getDefaultRole(Long companyId) {
        // 查询企业的默认角色（"默认角色"）
        com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role> queryWrapper = 
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role>()
                .eq("app", "enterprise")
                .eq("scope", "tenant")
                .eq("company_id", companyId)
                .eq("role_name", "默认角色")
                .eq("is_active", 1);
        
        List<Role> roles = roleMapper.selectList(queryWrapper);
        return roles.isEmpty() ? null : roles.get(0);
    }
    
    @Override
    public Role getDefaultPlatformRole() {
        // 查询平台端的默认角色（"默认角色"）
        com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role> queryWrapper = 
            new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<Role>()
                .eq("app", "platform")
                .eq("scope", "platform")
                .eq("role_name", "默认角色")
                .eq("is_active", 1);
        
        List<Role> roles = roleMapper.selectList(queryWrapper);
        return roles.isEmpty() ? null : roles.get(0);
    }
}
